package com.gagakuai.engine.impl.pvm.runtime;

import com.gagakuai.engine.impl.pvm.PvmActivity;
import com.gagakuai.engine.impl.pvm.PvmEvent;
import com.gagakuai.engine.impl.pvm.process.ActivityImpl;
import com.gagakuai.engine.impl.pvm.process.ProcessDefinitionImpl;
import com.gagakuai.engine.impl.pvm.process.ScopeImpl;
import com.gagakuai.engine.impl.runtime.InterpretableExecution;

import java.util.List;

/*
 * @program: common-starters
 * @description:
 * @author: houhong
 * @create: 2023-01-02 20:02
 */
public class AtomicOperationProcessStartInitial  extends AbstractEventAtomicOperation{
    @Override
    protected String getEventName() {
        return PvmEvent.EVENTNAME_START;
    }

    @Override
    protected ScopeImpl getScope(InterpretableExecution execution) {
         return (ScopeImpl) execution.getActivity();
    }

    @Override
    protected void eventNotificationsCompleted(InterpretableExecution execution) {

        //活动
        ActivityImpl activity = (ActivityImpl)execution.getActivity();
        //流程定义
        ProcessDefinitionImpl processDefinition = execution.getProcessDefinition();
        //
        StartingExecution startingExecution = execution.getStartingExecution();

        /*
         *  1:通过execution获取ActivityImpl (对应开始节点的ActivityImpl)
         *  2:通过execution获取ActivityImpl StartingExecution
         *  3：判断execution中的 ActivityImpl 和  StartingExecution 中的ActivityImpl
         *  是否一样？
         *  如果一样 就执行 disposeStartingExecution
         *  否则就重新获取
         *  目的： 确保流程实列中的启动节点和流程文档中定义的是同一个节点
         *
         */
        if(activity == startingExecution.getInitial()){
            //将执行中的 startingExecution 置空
            execution.disposeStartingExecution();
            //执行下一步

        }else {
            //重新获取
            List<ActivityImpl> initialActivityStack = processDefinition.getInitialActivityStack(startingExecution.getInitial());
            int index = initialActivityStack.indexOf(activity);
            activity = initialActivityStack.get(index + 1);

            InterpretableExecution executionToUse = null;
            if (activity.isScope()) {
                executionToUse = (InterpretableExecution) execution.getExecutions().get(0);
            } else {
                executionToUse = execution;
            }
            executionToUse.setActivity(activity);
            executionToUse.performOperation(PROCESS_START_INITIAL);
        }
    }
}